package net.dgg.zz.flownode.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.dgg.framework.tac.utils.idutil.DggKeyWorker;
import net.dgg.iboss.base.service.CmsService;
import net.dgg.tmd.foundation.platform.session.SessionManager;
import net.dgg.tmd.foundation.platform.user.entity.UserEntity;
import net.dgg.zz.common.base.service.BaseService;
import net.dgg.zz.common.excption.CommonExcption;
import net.dgg.zz.common.utils.StringUtils;
import net.dgg.zz.common.utils.ValidateUtils;
import net.dgg.zz.flownode.dao.ZzProductNodeDao;
import net.dgg.zz.flownode.dao.ZzProductNodeFieldDao;
import net.dgg.zz.flownode.dao.ZzProductNodeFlowDao;
import net.dgg.zz.production.inProcess.entity.ProductNode;
import net.dgg.zz.production.inProcess.entity.ProductNodeField;
import net.dgg.zz.production.inProcess.entity.ProductNodeFlow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @class_name: NodeManager
 * @package: net.dgg.iboss.sccenter.sc.service
 * @describe: TODO 节点管理 service层
 * @author: 孙上峰
 * @creat_date: 2018/8/28
 * @creat_time: 11:48
 **/
@Service
public class FlowNodeService extends BaseService {

    @Autowired
    private ZzProductNodeFlowDao zzProductNodeFlowDao;

    @Autowired
    private ZzProductNodeFieldDao zzProductNodeFieldDao;

    @Autowired
    private ZzProductNodeDao zzProductNodeDao;

    @Autowired
    private SessionManager sessionManager;
    @Autowired
    private CmsService cmsService;

    /**
     * 根据条件搜索用户DTO并返回
     *
     * @param keyWords
     * @return
     */
    @Transactional(readOnly = true)
    public List<ProductNodeFlow> findAllFlowWithPage(Map map) {
        Integer count = this.zzProductNodeFlowDao.count(map);
        map.put("count", count);
        if (count <= 0) {
            return new ArrayList<ProductNodeFlow>(0);
        }
        if (null == map.get("orderColumn")) {
            map.put("orderDir", "desc");
            map.put("orderColumn", "updateTime");
        }
        List<ProductNodeFlow> scProductNodeFlowList = zzProductNodeFlowDao.query(map);
        return scProductNodeFlowList;
    }

    /**
     * @Title:
     * @Description: TODO 数量统计
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/16
     **/
    @Transactional(readOnly = true)
    public Integer countAllFlowWithPage(Map map) {
        Integer count = zzProductNodeFlowDao.count(map);
        return count;
    }


    /**
     * @Title:
     * @Description: TODO 根据flowID获取流程信息
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/8
     **/
    @Transactional(readOnly = true)
    public ProductNodeFlow findFlowById(Map map) {
        Assert.notNull(map.get("flowId"), "流程ID传入失败！");
        ProductNodeFlow sc_Flow = zzProductNodeFlowDao.queryFlowById(map);
        Assert.notNull(sc_Flow, "流程查询失败！");
        return sc_Flow;
    }

    /**
     * @Title:
     * @Description: TODO 获取节点信息list
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/9
     **/
    @Transactional(readOnly = true)
    public List<ProductNode> findNodeList(Map map) {
        List<ProductNode> sc_NodeList = zzProductNodeDao.query(map);
        return sc_NodeList;
    }

    /**
     * @Title:
     * @Description: TODO 根据flowId获取除接单、完结外的节点信息list
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/9
     **/
    @Transactional(readOnly = true)
    public List<ProductNode> findNodeCenterById(Map map) {
        Assert.notNull(map.get("flowId"), "流程ID传入失败！");
        List<ProductNode> sc_NodeList = zzProductNodeDao.queryNodeCenter(map);
        return sc_NodeList;
    }

    /**
     * @Title:
     * @Description: TODO 根据flowId获取接单节点信息ScProductNode
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/9
     **/
    @Transactional(readOnly = true)
    public ProductNode findNodeJdById(Map map, List<ProductNode> sc_NodeList) {
        Assert.notNull(map.get("flowId"), "流程ID传入失败！");
        ProductNode nodeJd = zzProductNodeDao.queryNodeJd(map);
        Assert.notNull(nodeJd, "接单节点出现异常，请联系管理员！");
        if (sc_NodeList == null && nodeJd != null) {
            throw new CommonExcption("流程出现异常，请联系管理员！");
        }
        return nodeJd;
    }

    /**
     * @Title:
     * @Description: TODO 根据flowId获取强制完结节点信息ScProductNode
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/9
     **/
    @Transactional(readOnly = true)
    public ProductNode findNodeQzWjById(Map map, List<ProductNode> sc_NodeList) {
        Assert.notNull(map.get("flowId"), "流程ID传入失败！");
        ProductNode nodeQzWj = zzProductNodeDao.queryNodeQzWj(map);
        Assert.notNull(nodeQzWj, "强制完结节点出现异常，请联系管理员！");
        if (sc_NodeList == null && nodeQzWj != null) {
            throw new CommonExcption("流程出现异常，请联系管理员！");
        }
        return nodeQzWj;
    }

    /**
     * @Title:
     * @Description: TODO 根据flowId获取完结节点信息ScProductNode
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/9
     **/
    @Transactional(readOnly = true)
    public ProductNode findNodeWjById(Map map, List<ProductNode> sc_NodeList) {
        Assert.notNull(map.get("flowId"), "流程ID传入失败！");
        ProductNode nodeWj = zzProductNodeDao.queryNodeWj(map);
        Assert.notNull(nodeWj, "完结节点出现异常，请联系管理员！");
        if (sc_NodeList == null && nodeWj != null) {
            throw new CommonExcption("流程出现异常，请联系管理员！");
        }
        return nodeWj;
    }

    /**
     * @Title:
     * @Description: TODO 根据事业部ID获取关键字段信息
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/8
     **/
    @Transactional(readOnly = true)
    public List<ProductNodeField> findNodefield(Map map) {
        List<ProductNodeField> sc_NodeFieldList = zzProductNodeFieldDao.query(map);
        return sc_NodeFieldList;
    }

    /**
     * @Title:
     * @Description: TODO 新增或者保存流程信息
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/21
     **/
    @Transactional
    public void saveFlow(Map params) {
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        Assert.notNull(sessionUser, "未获取到当前登陆人！");
        ProductNodeFlow flow = new ProductNodeFlow();
        if (params.get("flowId") != null) {
            Map tjmap = new HashMap();
            tjmap.put("flowId", String.valueOf(params.get("flowId")));
            tjmap.put("flag", 1);
            flow = zzProductNodeFlowDao.queryFlowById(tjmap);
        }
        flow.setDeptIds(Long.parseLong(String.valueOf(params.get("orgId"))));
        String buscode = "";
        if (null == params.get("typeCodeAdd")) {
            buscode = String.valueOf(params.get("typeCodeEdit"));
            flow.setDeptNames(String.valueOf(params.get("selectTreeAddressIdEdit")));
        } else {
            buscode = String.valueOf(params.get("typeCodeAdd"));
            flow.setDeptNames(String.valueOf(params.get("selectTreeAddRessId")));
        }
        Map busCodeMap = cmsService.getTreeBookObj(buscode);
        Map BigFormatCodeMap = cmsService.getTreeBookObj(String.valueOf(busCodeMap.get("pcode")));


        flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
        flow.setManagementCycle(Integer.parseInt(String.valueOf(params.get("blDate"))));
        flow.setIsnaturalorworkday(Integer.parseInt(String.valueOf(params.get("isnaturalorworkday"))));
        flow.setExamineGrade(Integer.parseInt(String.valueOf(params.get("examinGrade"))));

        List<Map> ue = new ArrayList<>();
        String buslevel = String.valueOf(busCodeMap.get("levels"));
        int num = appearNumber(buslevel, "_");
        if (num == 3) {
            flow.setBigformatCode(String.valueOf(busCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(busCodeMap.get("name")));
            flow.setBusinessCode(null);
            flow.setBusinessName(null);
            ue = zzProductNodeFlowDao.findFlowEntityByBigFormatCode(flow);
        } else if (num == 4) {
            flow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
            flow.setBusinessCode(String.valueOf(busCodeMap.get("code")));
            flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
            ue = zzProductNodeFlowDao.findFlowEntityByBusiness(flow);
        } else {
            throw new CommonExcption("业态类型出现异常！");
        }
        if (ue.size() > 0) {
            throw new CommonExcption("保存失败，该业态流程已存在！");
        }
        if (flow.getId() == null) {// 新增
            long id = DggKeyWorker.nextId();
            flow.setId(id);
            String number = cmsService.getBillNumber("LC");
            ValidateUtils.isTrue(StringUtils.isNotEmpty(number), CommonExcption.class, "单据号获取失败,请联系管理员");
            flow.setFlowNo(number);
            flow.setFlag(1);
            this.saveOpt(flow, sessionUser);
            zzProductNodeFlowDao.save(flow);

            ProductNode jdnode = new ProductNode();
            jdnode.setId(DggKeyWorker.nextId());
            jdnode.setName("接单");
            jdnode.setHandleDate(1);
            jdnode.setIsNaturalorWorkday(1);
            jdnode.setIsKey(1);
            jdnode.setSort(1);
            jdnode.setProcessId(id);
            jdnode.setFlag(1);
            this.saveOpt(jdnode, sessionUser);

            ProductNode qzwjnode = new ProductNode();
            qzwjnode.setId(DggKeyWorker.nextId());
            qzwjnode.setName("强制完结");
            qzwjnode.setHandleDate(1);
            qzwjnode.setIsNaturalorWorkday(1);
            qzwjnode.setIsKey(1);
            qzwjnode.setSort(2);
            qzwjnode.setProcessId(id);
            qzwjnode.setFlag(1);
            this.saveOpt(qzwjnode, sessionUser);

            ProductNode wjnode = new ProductNode();
            wjnode.setId(DggKeyWorker.nextId());
            wjnode.setName("完结");
            wjnode.setHandleDate(1);
            wjnode.setIsNaturalorWorkday(1);
            wjnode.setIsKey(1);
            wjnode.setSort(3);
            wjnode.setProcessId(id);
            wjnode.setFlag(1);
            this.saveOpt(wjnode, sessionUser);

            zzProductNodeDao.save(jdnode);
            zzProductNodeDao.save(qzwjnode);
            zzProductNodeDao.save(wjnode);
        } else {
            this.updateOpt(flow, sessionUser);
            zzProductNodeFlowDao.update(flow);
        }
    }

    /**
     * @Title:
     * @Description: TODO 保存节点信息
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/21
     **/
    @Transactional
    public void saveNode(ProductNode node, Map params) {
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        Assert.notNull(sessionUser, "未获取到当前登陆人！");
        Map tjmap = new HashMap();
        Long flowid = Long.parseLong(params.get("flowid").toString());
        tjmap.put("flowId", flowid);
        ProductNodeFlow scProNodeFlow = zzProductNodeFlowDao.queryFlowById(tjmap);
        Assert.notNull(scProNodeFlow, "流程信息获取出现异常！");
        JSONArray jsonArray = JSONArray.parseArray(params.get("jsonData").toString());
        if (jsonArray.size() > 0) {
            StringBuffer str = new StringBuffer();
            List list = new ArrayList();
            for (int i = 0; i < jsonArray.size(); i++) {
                ProductNode scProFlowNode = new ProductNode();
                JSONObject job = jsonArray.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
                Long nodeid = (job.get("nodeid") == null || job.get("nodeid").equals("")) ? DggKeyWorker.nextId() : Long.parseLong(job.get("nodeid").toString());
                scProFlowNode.setId(nodeid);
                scProFlowNode.setName(job.get("Nodename").toString());
                scProFlowNode.setSort(Integer.parseInt(job.get("Xuhao").toString()));
                scProFlowNode.setProcessId(flowid);

                int handledate = Integer.parseInt(job.get("Nodecycle").toString());
                Assert.isTrue(handledate > 0, "节点办理周期必须大于0！");
                scProFlowNode.setHandleDate(handledate);
                scProFlowNode.setRelationField(job.get("Nodecruxfield").toString());
                scProFlowNode.setRelationFieldIds(job.get("nodecruxfieldids").toString());
                scProFlowNode.setIsKey(Integer.parseInt(job.get("Iscurxnode").toString()));
                scProFlowNode.setIsNaturalorWorkday(Integer.parseInt(job.get("isNaturalorWorkday").toString()));
                scProFlowNode.setFlag(1);
                if (job.get("nodeid") == null || job.get("nodeid").equals("")) {
                    this.saveOpt(scProFlowNode, sessionUser);
                    zzProductNodeDao.save(scProFlowNode);
                } else {
                    this.updateOpt(scProFlowNode, sessionUser);
                    zzProductNodeDao.update(scProFlowNode);
                }
                list.add(nodeid);
            }
            tjmap.put("nodeids", list);
            tjmap.put("flowid", flowid);
            zzProductNodeDao.delNodeListByIds(tjmap);
            this.updateOpt(scProNodeFlow, sessionUser);
            zzProductNodeFlowDao.update(scProNodeFlow);
        }
    }

    /**
     * @Title:
     * @Description: TODO 复制流程保存
     * @param:
     * @return:
     * @throw:
     * @author: 代杨
     * @creat_date: 2018/5/22
     **/
    @Transactional
    public void copyFlowAndFlow(Map params) {
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        Assert.notNull(sessionUser, "未获取到当前登陆人！");
        if (params.get("flowId") == null || params.get("flowId").equals("")) {
            throw new CommonExcption("生产流程ID出现错误！");
        }
        ProductNodeFlow newflow = new ProductNodeFlow();
        newflow.setDeptIds(Long.parseLong(String.valueOf(params.get("orgId"))));
        newflow.setDeptNames(String.valueOf(params.get("selectTreeAddressIdCopy")));
        String buscode = String.valueOf(params.get("typeCodeCopy"));
        Map busCodeMap = cmsService.getTreeBookObj(buscode);
        Map BigFormatCodeMap = cmsService.getTreeBookObj(String.valueOf(busCodeMap.get("pcode")));
        newflow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
        newflow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
        newflow.setManagementCycle(Integer.parseInt(String.valueOf(params.get("blDate"))));
        newflow.setIsnaturalorworkday(Integer.parseInt(String.valueOf(params.get("isnaturalorworkday"))));
        newflow.setExamineGrade(Integer.parseInt(String.valueOf(params.get("examinGrade"))));

        List<Map> ue = new ArrayList<>();
        String buslevel = String.valueOf(busCodeMap.get("levels"));
        int num = appearNumber(buslevel, "_");
        if (num == 3) {
            newflow.setBigformatCode(String.valueOf(busCodeMap.get("code")));
            newflow.setBigformatName(String.valueOf(busCodeMap.get("name")));
            newflow.setBusinessCode(null);
            newflow.setBusinessName(null);
            ue = zzProductNodeFlowDao.findFlowEntityByBigFormatCode(newflow);
        } else if (num == 4) {
            newflow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
            newflow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
            newflow.setBusinessCode(String.valueOf(busCodeMap.get("code")));
            newflow.setBusinessName(String.valueOf(busCodeMap.get("name")));
            ue = zzProductNodeFlowDao.findFlowEntityByBusiness(newflow);
        } else {
            throw new CommonExcption("业态类型出现异常！");
        }
        if (ue.size() > 0) {
            throw new CommonExcption("保存失败，该业态流程已存在！");
        }
        long newflowid = DggKeyWorker.nextId();
        newflow.setId(newflowid);
        String flowno = cmsService.getBillNumber("LC");
        newflow.setFlowNo(flowno);
        newflow.setFlag(1);
        this.saveOpt(newflow, sessionUser);

        zzProductNodeFlowDao.save(newflow);

        Map tjmap = new HashMap();
        tjmap.put("flowId", String.valueOf(params.get("flowId")));
        List<ProductNode> nodelist = zzProductNodeDao.queryByFlowId(tjmap);
        ProductNodeFlow scProNodeFlow = zzProductNodeFlowDao.queryFlowById(tjmap);

        if (nodelist.size() > 0) {
            for (ProductNode node : nodelist) {
                ProductNode newnode = new ProductNode();
                newnode.setId(DggKeyWorker.nextId());
                newnode.setName(node.getName());
                newnode.setSort(node.getSort());
                newnode.setProcessId(newflowid);
                newnode.setHandleDate(node.getHandleDate());
                if (scProNodeFlow.getBigformatCode().equals(newflow.getBigformatCode())) {
                    newnode.setRelationField(node.getRelationField());
                    newnode.setRelationFieldIds(node.getRelationFieldIds());
                }
                newnode.setIsKey(node.getIsKey());
                newnode.setIsNaturalorWorkday(node.getIsNaturalorWorkday());
                newnode.setFlag(1);
                this.saveOpt(newnode, sessionUser);
                zzProductNodeDao.save(newnode);
            }
        }
    }

    /**
     * public int indexOf(int ch, int fromIndex)
     * 返回在此字符串中第一次出现指定字符处的索引，从指定的索引开始搜索
     *
     * @param srcText
     * @param findText
     * @return
     */
    public static int appearNumber(String srcText, String findText) {
        int count = 0;
        int index = 0;
        while ((index = srcText.indexOf(findText, index)) != -1) {
            index = index + findText.length();
            count++;
        }
        return count;
    }
}
